Skip to content

(de)serialize dates w/ ISO8601 (#683) #4450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

nVitius
Copy link

@nVitius nVitius commented Feb 10, 2021

There's been an issue (#683) open for a few years asking for serialization of dates for httpsCallables.
It seemed like something really easy to do, so I created this PR as a proposal for how we might consider doing it.

Encoding is done with Date.toISOString. JavaScript's JSON.stringify also uses Date.toISOString to encode Dates (ref, ref). Decoding tests Strings against a RegEx that matches ISO 8601 strings.

It would be nice to support a more robust serialization that also supports Firestore data types (Timestamp, GeoPoint, Reference). Perhaps we could eventually use the same serialization format that the Firestore REST API uses. I do think that would require more coordination efforts across both libs to deploy without breaking any compatibility.

Ideally, this change would be accompanied by a similar change on the firebase-functions repo.
However, it looks like the actual code for encoding/decoding onCall functions is actually private.
https://github.com/firebase/firebase-functions/blob/master/src/providers/https.ts#L377
https://github.com/firebase/firebase-functions/blob/master/src/providers/https.ts#L339
At least, that's what I understood from the comments on those functions.

For what it's worth, the existing implementation doesn't work with Date types at all. It converts them to { date: {} }. I don't believe that merging this will break anything even if the firebase-functions isn't updated at the same time.

@changeset-bot
Copy link

changeset-bot bot commented Feb 10, 2021

⚠️ No Changeset found

Latest commit: 22454da

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@google-cla
Copy link

google-cla bot commented Feb 10, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@nVitius
Copy link
Author

nVitius commented Feb 10, 2021

@googlebot I signed it!

@nVitius
Copy link
Author

nVitius commented Feb 18, 2021

@Feiyang1 @hiranya911 @hsubox76
Can get some feedback on this PR/Issue?

@nVitius
Copy link
Author

nVitius commented Mar 1, 2021

@Feiyang1 @hiranya911 @hsubox76
Just pinging you guys again. Would appreciate some feedback here.

The underlying issue has been open for almost three years now. It seems to be an easy fix (the change in this PR is non-breaking btw). If there's something blocking this, it would be great to know about it.

Let me know if there's someone else I should ping to review this.

@hsubox76 hsubox76 self-assigned this Mar 2, 2021
@hsubox76
Copy link
Contributor

hsubox76 commented Mar 2, 2021

Thanks, I will discuss this with other teams (functions backend, other platforms such as iOS and Android) to try to get background and make sure we're not missing any context and it won't have any unintended effects. We also probably want changes to be made in sync with the other platforms (iOS, Android).

@nVitius
Copy link
Author

nVitius commented Apr 30, 2021

@hsubox76 Following up on this:
Were you able to bring this issue up with the other Firebase teams? Can we get some feedback on the status of this issue?

I mentioned it before, but the current implementation doesn't work with dates at all. Presumably, anyone using this to send dates is using their own workaround. The change proposed in this PR is non-breaking.

@hsubox76
Copy link
Contributor

Yes, I did bring it up with the other teams and the larger issue was too complex to reach a conclusion on, but we decided to fix the immediate bug we want to JSON.stringify() the entire data object on the way to the server, so that all data is at least serialized in a predictable, consistent way, instead of the surprise of having a Date be an empty object.

We don't want to automatically deserialize ISO strings returned from the server into Date objects, in case someone intentionally is sending an ISO formatting string back and wants to keep it as a string.

I was planning to make these changes this week but have not had time yet due to a number of pressing beta releases. If you have time to change this PR to reflect the plan above, we can merge it.

A full solution for functions handling special data types on the server side and passing type data back to the deserializer, etc. will probably be a long term feature I'm not sure I can promise any timeline or prioritization on yet.

@nVitius
Copy link
Author

nVitius commented Apr 30, 2021

Thanks for your reply.

I can make the changes to the PR to remove the decoding, but I do think that it would be valuable to have.

I understand the reasoning for not wanting to automatically deserialize ISO strings. I'm obviously not familiar with the implications this would have to the larger issue, but I think it would make sense to encode them to an object like this:

{ _firebaseSerializedDate: `the iso string` }

This way, we can almost guarantee that only Date objects would be serialized/deserialized.

@hsubox76
Copy link
Contributor

hsubox76 commented May 3, 2021

That would definitely be a long-term solution as the server-side function would have to send some kind of standardized wrapper back to indicate the type, and the other platform SDKs (Android, iOS) would have to recognize this wrapper. There was an effort to do this in the past but it was never completed. Would like to see what we can do now but can't make any promises.

We can and should quickly fix the serialization error where a Date ends up as an empty object by JSON.stringifying the entire data object, since that can be entirely handled in the JS SDK. I hope to get to it soon if you don't have time. By the way, if you want to go through with it, this PR will also need a changeset (yarn changeset to add).

@hsubox76
Copy link
Contributor

Hope you don't mind, I've made a PR. We also needed to make the same change to the "exp" (modularized) version of functions that's currently in beta. #4887

@nVitius
Copy link
Author

nVitius commented May 18, 2021

Not at all. I'll close this one then.

@nVitius nVitius closed this May 18, 2021
@firebase firebase locked and limited conversation to collaborators Jun 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants